package com.pochoF1.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.parser.PdfTextExtractor;
import com.pochoF1.enums.Carreras;
import com.pochoF1.enums.Sesiones;
import com.pochoF1.exceptions.DescargarFiaException;
import com.pochoF1.exceptions.NoFileFiaException;
import com.pochoF1.model.Piloto;
import com.pochoF1.model.Vuelta;

public class LeerPDF {
	private static Logger log = LoggerFactory.getLogger(LeerPDF.class);

	private static void descargarPDF(Carreras carrera, Sesiones sesion) throws Exception {
		String urlS = Constants.urlSave + carrera.getCarreraString() + "/";
		String urlR = Constants.urlRead + carrera.getCarreraString() + "/";

		File files = new File(urlS);
		if (!files.exists()) {
			files.mkdirs();
		}

		if (sesion.equals(Sesiones.FP1)) {
			urlR += Constants.FP1R;
			urlS += Constants.FP1W;
		} else if (sesion.equals(Sesiones.FP2)) {
			urlR += Constants.FP2R;
			urlS += Constants.FP2W;
		} else if (sesion.equals(Sesiones.FP3)) {
			urlR += Constants.FP3R;
			urlS += Constants.FP3W;
		} else if (sesion.equals(Sesiones.QUALY)) {
			urlR += Constants.QUALYR;
			urlS += Constants.QUALYW;
		} else if (sesion.equals(Sesiones.RACE)) {
			urlR += Constants.RACER;
			urlS += Constants.RACEW;
		}

		File archivo = new File(urlS + ".pdf");
		if (!archivo.exists()) {
			log.info("Descargando el archivo: " + urlR.replace("%20", " ") + ".pdf");

			try {
				URL website = new URL(urlR + ".pdf");
				InputStream is = null;

				try {
					is = website.openStream();
				} catch (FileNotFoundException e) {
					log.info("No se pudo descargar el archivo " + e.getMessage());
					throw new DescargarFiaException(e.getMessage());
				}
				ReadableByteChannel rbc = Channels.newChannel(is);

				FileOutputStream fos = new FileOutputStream(urlS + ".pdf");
				fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
				fos.close();

				log.info("Guardando archivo: " + urlS + ".pdf");
			} catch (MalformedURLException e) {
				e.printStackTrace();
				throw new DescargarFiaException(e.getMessage());
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				throw new NoFileFiaException(e.getMessage());
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
		} else
			log.info("Ya existe el archivo: " + urlS + ".pdf");

	}

	private static void descargarPDF(String raceRound, String raceYear, String raceName, Sesiones sesion) throws Exception {
		String urlS = Constants.urlSavePDF + raceYear + "/" + raceRound + "/";
		String urlR = Constants.urlRead + raceYear + "/f1-" + raceYear + "-" + raceRound + "/";

		File files = new File(urlS);
		if (!files.exists()) {
			files.mkdirs();
		}

		if (sesion.equals(Sesiones.FP1)) {
			urlR += Constants.FP1R;
			urlS += Constants.FP1W;
		} else if (sesion.equals(Sesiones.FP2)) {
			urlR += Constants.FP2R;
			urlS += Constants.FP2W;
		} else if (sesion.equals(Sesiones.FP3)) {
			urlR += Constants.FP3R;
			urlS += Constants.FP3W;
		} else if (sesion.equals(Sesiones.QUALY)) {
			urlR += Constants.QUALYR;
			urlS += Constants.QUALYW;
		} else if (sesion.equals(Sesiones.RACE)) {
			urlR += Constants.RACER;
			urlS += Constants.RACEW;
		}

		File archivo = new File(urlS + ".pdf");
		if (!archivo.exists()) {
			log.info("Descargando el archivo: " + urlR.replace("%20", " ") + ".pdf");

			try {
				URL website = new URL(urlR + ".pdf");
				InputStream is = null;

				HttpURLConnection yc = Constants.obtenerHTTPConexion(website);

				try {
					is = yc.getInputStream();
				} catch (FileNotFoundException e) {
					log.info("No se pudo descargar el archivo " + e.getMessage());
					throw new DescargarFiaException(e.getMessage());
				}
				ReadableByteChannel rbc = Channels.newChannel(is);

				FileOutputStream fos = new FileOutputStream(urlS + ".pdf");
				fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
				fos.close();

				log.info("Guardando archivo: " + urlS + ".pdf");
			} catch (MalformedURLException e) {
				e.printStackTrace();
				throw new DescargarFiaException(e.getMessage());
			} catch (FileNotFoundException e) {
				e.printStackTrace();
				throw new NoFileFiaException(e.getMessage());
			} catch (IOException e) {
				e.printStackTrace();
				throw e;
			}
		} else
			log.info("Ya existe el archivo: " + urlS + ".pdf");
	}

	public static List<Piloto> leerPDF(Carreras carrera, Sesiones sesion) throws Exception {

		descargarPDF(carrera, sesion);

		String urlS = Constants.urlSave + carrera.getCarreraString() + "/";
		boolean proximaSalida = true;

		if (sesion.equals(Sesiones.FP1))
			urlS += Constants.FP1W;
		else if (sesion.equals(Sesiones.FP2))
			urlS += Constants.FP2W;
		else if (sesion.equals(Sesiones.FP3))
			urlS += Constants.FP3W;
		else if (sesion.equals(Sesiones.QUALY))
			urlS += Constants.QUALYW;
		else if (sesion.equals(Sesiones.RACE))
			urlS += Constants.RACEW;

		List<Piloto> pilotosSesion = new ArrayList<Piloto>();
		PdfReader reader = null;
		try {
			reader = new PdfReader(urlS + ".pdf");
			StringBuilder sb = new StringBuilder();
			PdfTextExtractor pdfTE = new PdfTextExtractor(reader);
			Piloto p = null;
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            	sb.append(pdfTE.getTextFromPage(i));
			}
            String[] lines = sb.toString().split("\\n");
            
            for (int i = 0; i < lines.length; i++) {
            	String s = lines[i];
            	if (s.contains("NO  NO  TIME       TIME       ") || s.contains("LAP  LAP  TIME       TIME       ")) {
					p = new Piloto();
					proximaSalida = true;
					String piloto = lines[i - 1].replace("\r", "");
					String numero = piloto.substring(0, piloto.indexOf(" "));
					String nombre = piloto.substring(piloto.indexOf(" ") + 1);
					p.setNombre(nombre);

					try {
						p.setNumero(Integer.parseInt(numero));
					} catch (Exception e) {
					}

					pilotosSesion.add(p);
				}
            	if (esUnaVueltaIText(s)) {
            		if (p != null) {
            			s = s.replace("\r", "");
            			String vueltaPit = lines[i - 1].replace("\r", "");
						Vuelta v = new Vuelta();
						int nroVuelta = 0;
						try {
							nroVuelta = Integer.parseInt(vueltaPit.split(" ")[0]);
						} catch (Exception e) {}
						v.setNroVuelta(nroVuelta);
						String tiempoVuelta = s.replace(" ", "");
						String _min = "";
						String _seg = "";
						String _milli = "";
						String[] tiempoSplit = tiempoVuelta.split(":");
						if (tiempoSplit.length > 2) {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1];
							_milli = tiempoSplit[2];
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						} else {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1].substring(0,tiempoSplit[1].indexOf("."));
							_milli = tiempoSplit[1].substring(tiempoSplit[1].indexOf(".")+1);
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						}
						int min = 0;
						int seg = 0;
						int milli = 0;
						
						try {min = Integer.parseInt(_min) * 60 * 1000;} catch (Exception e) {}
						try {seg = Integer.parseInt(_seg) * 1000;} catch (Exception e) {}
						try {milli = Integer.parseInt(_milli);} catch (Exception e) {}
						
						v.setTiempo(min + seg + milli);
						v.setTiempoVuelta(tiempoVuelta);
						v.setVueltaSalida(proximaSalida);
						
						if(vueltaPit.split(" ").length>1){
							v.setPits(true);
							proximaSalida = true;
						}else
							proximaSalida = false;
						
						p.getVueltasActuales().add(v);
            		}
            	}
            }
			

			if (reader != null) {
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return pilotosSesion;
	}

	public static List<Piloto> leerPDF(String raceRound, String raceYear, String raceName, Sesiones sesion) throws Exception {

		descargarPDF(raceRound, raceYear, raceName, sesion);

		String urlS = Constants.urlSavePDF + raceYear + "/" + raceRound + "/";
		boolean proximaSalida = true;

		if (sesion.equals(Sesiones.FP1))
			urlS += Constants.FP1W;
		else if (sesion.equals(Sesiones.FP2))
			urlS += Constants.FP2W;
		else if (sesion.equals(Sesiones.FP3))
			urlS += Constants.FP3W;
		else if (sesion.equals(Sesiones.QUALY))
			urlS += Constants.QUALYW;
		else if (sesion.equals(Sesiones.RACE))
			urlS += Constants.RACEW;

		List<Piloto> pilotosSesion = new ArrayList<Piloto>();
		PdfReader reader = null;
		try {
			reader = new PdfReader(urlS + ".pdf");
			StringBuilder sb = new StringBuilder();
			PdfTextExtractor pdfTE = new PdfTextExtractor(reader);
			Piloto p = null;
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            	sb.append(pdfTE.getTextFromPage(i));
			}
            String[] lines = sb.toString().split("\\n");
            
            for (int i = 0; i < lines.length; i++) {
            	String s = lines[i];
            	if (s.contains("NO  NO  TIME       TIME       ") || s.contains("LAP  LAP  TIME       TIME       ")) {
					p = new Piloto();
					proximaSalida = true;
					String piloto = lines[i - 1].replace("\r", "");
					String numero = piloto.substring(0, piloto.indexOf(" "));
					String nombre = piloto.substring(piloto.indexOf(" ") + 1);
					p.setNombre(nombre);

					try {
						p.setNumero(Integer.parseInt(numero));
					} catch (Exception e) {
					}

					pilotosSesion.add(p);
				}
            	if (esUnaVueltaIText(s)) {
            		if (p != null) {
            			s = s.replace("\r", "");
            			String vueltaPit = lines[i - 1].replace("\r", "");
						Vuelta v = new Vuelta();
						int nroVuelta = 0;
						try {
							nroVuelta = Integer.parseInt(vueltaPit.split(" ")[0]);
						} catch (Exception e) {}
						v.setNroVuelta(nroVuelta);
						String tiempoVuelta = s.replace(" ", "");
						String _min = "";
						String _seg = "";
						String _milli = "";
						String[] tiempoSplit = tiempoVuelta.split(":");
						if (tiempoSplit.length > 2) {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1];
							_milli = tiempoSplit[2];
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						} else {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1].substring(0,tiempoSplit[1].indexOf("."));
							_milli = tiempoSplit[1].substring(tiempoSplit[1].indexOf(".")+1);
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						}
						int min = 0;
						int seg = 0;
						int milli = 0;
						
						try {min = Integer.parseInt(_min) * 60 * 1000;} catch (Exception e) {}
						try {seg = Integer.parseInt(_seg) * 1000;} catch (Exception e) {}
						try {milli = Integer.parseInt(_milli);} catch (Exception e) {}
						
						v.setTiempo(min + seg + milli);
						v.setTiempoVuelta(tiempoVuelta);
						v.setVueltaSalida(proximaSalida);
						
						if(vueltaPit.split(" ").length>1){
							v.setPits(true);
							proximaSalida = true;
						}else
							proximaSalida = false;
						
						p.getVueltasActuales().add(v);
            		}
            	}
            }
			

			if (reader != null) {
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return pilotosSesion;
	}

	public static List<Piloto> leerPDF(String raceRound, String raceYear, String raceName, Sesiones sesion, String raceId) throws Exception {

		descargarPDF(raceRound, raceYear, raceName, sesion);

		String urlS = Constants.urlSavePDF + raceYear + "/" + raceRound + "/";
		boolean proximaSalida = true;

		if (sesion.equals(Sesiones.FP1))
			urlS += Constants.FP1W;
		else if (sesion.equals(Sesiones.FP2))
			urlS += Constants.FP2W;
		else if (sesion.equals(Sesiones.FP3))
			urlS += Constants.FP3W;
		else if (sesion.equals(Sesiones.QUALY))
			urlS += Constants.QUALYW;
		else if (sesion.equals(Sesiones.RACE))
			urlS += Constants.RACEW;

		List<Piloto> pilotosSesion = new ArrayList<Piloto>();
		PdfReader reader = null;
		try {
			reader = new PdfReader(urlS + ".pdf");
			StringBuilder sb = new StringBuilder();
			PdfTextExtractor pdfTE = new PdfTextExtractor(reader);
			Piloto p = null;
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            	sb.append(pdfTE.getTextFromPage(i));
			}
            String[] lines = sb.toString().split("\\n");
            
            for (int i = 0; i < lines.length; i++) {
            	String s = lines[i];
            	if (s.contains("NO  NO  TIME       TIME       ") || s.contains("LAP  LAP  TIME       TIME       ")) {
					p = new Piloto();
					proximaSalida = true;
					String piloto = lines[i - 1].replace("\r", "");
					String numero = piloto.substring(0, piloto.indexOf(" "));
					String nombre = piloto.substring(piloto.indexOf(" ") + 1);
					p.setNombre(nombre);

					try {
						p.setNumero(Integer.parseInt(numero));
					} catch (Exception e) {
					}

					pilotosSesion.add(p);
				}
            	if (esUnaVueltaIText(s)) {
            		if (p != null) {
            			s = s.replace("\r", "");
            			String vueltaPit = lines[i - 1].replace("\r", "");
						Vuelta v = new Vuelta();
						int nroVuelta = 0;
						try {
							nroVuelta = Integer.parseInt(vueltaPit.split(" ")[0]);
						} catch (Exception e) {}
						v.setNroVuelta(nroVuelta);
						String tiempoVuelta = s.replace(" ", "");
						String _min = "";
						String _seg = "";
						String _milli = "";
						String[] tiempoSplit = tiempoVuelta.split(":");
						if (tiempoSplit.length > 2) {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1];
							_milli = tiempoSplit[2];
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						} else {
							_min = tiempoSplit[0];
							_seg = tiempoSplit[1].substring(0,tiempoSplit[1].indexOf("."));
							_milli = tiempoSplit[1].substring(tiempoSplit[1].indexOf(".")+1);
							_milli = _milli.length() >= 2 ? _milli.concat("0") : _milli.concat("00");
						}
						int min = 0;
						int seg = 0;
						int milli = 0;
						
						try {min = Integer.parseInt(_min) * 60 * 1000;} catch (Exception e) {}
						try {seg = Integer.parseInt(_seg) * 1000;} catch (Exception e) {}
						try {milli = Integer.parseInt(_milli);} catch (Exception e) {}
						
						v.setTiempo(min + seg + milli);
						v.setTiempoVuelta(tiempoVuelta);
						v.setVueltaSalida(proximaSalida);
						
						if(vueltaPit.split(" ").length>1){
							v.setPits(true);
							proximaSalida = true;
						}else
							proximaSalida = false;
						
						p.getVueltasActuales().add(v);
            		}
            	}
            }
			

			if (reader != null) {
				reader.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

		return pilotosSesion;
	}

	private static Boolean esUnaVueltaIText(String linea) {

		Pattern pattern = Pattern.compile("(\\d\\d[:]\\d\\d[:]\\d\\d)|(\\d\\d[:]\\d\\d[.]\\d\\d\\d)|(\\d[:]\\d\\d[.]\\d\\d\\d)|(\\d\\d[:]\\d\\d[:]\\d\\d)|(\\d\\d[:]\\d\\d[.]\\d\\d\\d)|(\\d[:]\\d\\d[.]\\d\\d\\d)");
		Matcher matcher = pattern.matcher(linea);
		if (matcher.find())
			return true;
		return false;
	}
	
}
